GridCore: add methods to HeaderPanel to add/remove toolbar items#33118
GridCore: add methods to HeaderPanel to add/remove toolbar items#33118anna-shakhova wants to merge 7 commits intoDevExpress:26_1from
Conversation
a88207d to
e6e56e6
Compare
There was a problem hiding this comment.
Pull request overview
This PR introduces a mechanism for dynamically managing GridCore header panel toolbar items by adding explicit addToolbarItem / removeToolbarItem APIs on HeaderPanel, and refactors the search panel integration to use these APIs (via a new controller) instead of extending HeaderPanel directly.
Changes:
- Added
HeaderPanel.addToolbarItem()/removeToolbarItem()with centralized sorting bysortIndex. - Refactored the search panel toolbar integration into
SearchPanelViewControllerthat registers/unregisters the search toolbar item on option changes. - Updated/added tests (QUnit + Jest integration) and adjusted related typing for toolbar items.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/keyboardNavigation.keyboardKeys.tests.js | Adjusts test setup ordering for searchPanel options before module initialization. |
| packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/headerPanel.tests.js | Switches tests to use this.option('searchPanel', ...) instead of mutating this.options.searchPanel. |
| packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/gridView.tests.js | Refactors one test’s grid creation/render flow; currently includes a stray debugger. |
| packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/dataGrid.tests.js | Removes an assertion that toolbar recomputation happens on searchPanel option changes. |
| packages/devextreme/js/__internal/grids/new/grid_core/toolbar/utils.ts | Formatting-only change to the types import. |
| packages/devextreme/js/__internal/grids/new/grid_core/toolbar/types.ts | Extends toolbar item typing with sortIndex and onItemRendered. |
| packages/devextreme/js/__internal/grids/grid_core/search/m_search.ts | Introduces SearchPanelViewController and registers/unregisters the search toolbar item dynamically. |
| packages/devextreme/js/__internal/grids/grid_core/search/tests/m_search.integration.test.ts | New Jest integration tests covering searchPanel runtime option changes without headerPanel invalidation. |
| packages/devextreme/js/__internal/grids/grid_core/m_types.ts | Adds searchPanel to the controllers typing map. |
| packages/devextreme/js/__internal/grids/grid_core/keyboard_navigation/m_keyboard_navigation.ts | Routes Ctrl+F focus behavior through the new searchPanel controller. |
| packages/devextreme/js/__internal/grids/grid_core/header_panel/m_header_panel.ts | Implements toolbar item registry + sorting, and wires onItemRendered passthrough. |
| packages/devextreme/js/__internal/grids/grid_core/header_panel/tests/m_header_panel.integration.test.ts | New Jest integration tests for the new headerPanel toolbar item registry APIs. |
| packages/devextreme/js/__internal/grids/grid_core/filter/m_filter_row.ts | Updates typing of headerPanel toolbar items to the shared ToolbarItem type. |
| packages/devextreme/js/__internal/grids/data_grid/export/m_export.ts | Removes local sort helper, relying on headerPanel’s centralized sorting. |
packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/gridView.tests.js
Outdated
Show resolved
Hide resolved
packages/devextreme/js/__internal/grids/new/grid_core/toolbar/types.ts
Outdated
Show resolved
Hide resolved
packages/devextreme/js/__internal/grids/grid_core/header_panel/m_header_panel.ts
Show resolved
Hide resolved
packages/devextreme/js/__internal/grids/grid_core/header_panel/m_header_panel.ts
Show resolved
Hide resolved
packages/devextreme/js/__internal/grids/grid_core/search/m_search.ts
Outdated
Show resolved
Hide resolved
06979b3 to
39dc044
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (1)
packages/devextreme/js/__internal/grids/grid_core/search/m_search.ts:165
SearchPanelViewController.optionChangedonly reacts tosearchPanel.textandsearchPanel.visible, but it marks allsearchPanel*changes as handled. This breaks common update paths likeoption('searchPanel', { visible: true, ... })(fullName === 'searchPanel') because the controller won't register/unregister the toolbar item, so the search panel never appears/disappears. It also prevents runtime updates toplaceholder/widthwhen visible. Consider handlingfullName === 'searchPanel'(and other relevantsearchPanel.*options) by updating/re-registering the toolbar item and/or updating the existing TextBox instance when already visible.
public optionChanged(args: OptionChanged): void {
if (args.name === 'searchPanel') {
if (args.fullName === 'searchPanel.text') {
const editor = this.getSearchTextEditor();
if (editor) {
editor.option('value', args.value);
}
}
if (args.fullName === 'searchPanel.visible') {
this._updateSearchPanelItem();
}
args.handled = true;
} else {
packages/devextreme/js/__internal/grids/grid_core/header_panel/m_header_panel.ts
Outdated
Show resolved
Hide resolved
f6f7cd9 to
a437a97
Compare
packages/devextreme/js/__internal/grids/grid_core/search/m_search.ts
Outdated
Show resolved
Hide resolved
packages/devextreme/js/__internal/grids/grid_core/keyboard_navigation/m_keyboard_navigation.ts
Outdated
Show resolved
Hide resolved
| this._registeredToolbarItems.set(name, { ...item, name }); | ||
|
|
||
| if (this._$element) { | ||
| this._invalidate(); |
There was a problem hiding this comment.
Why do we need to call the _invalidate method here? This method is only used in optionChanged.
There was a problem hiding this comment.
Agree, not necessary to redraw the whole headerPanel when we just update some property of button/editor
replaced it with more complex logic - of item already exists, we just update its options, otherwise redraw header panel to add item
| this._registeredToolbarItems.delete(name); | ||
|
|
||
| if (this._$element) { | ||
| this._invalidate(); |
There was a problem hiding this comment.
Why do we need to call the _invalidate method here? This method is only used in optionChanged.
There was a problem hiding this comment.
we need it there to redraw toolbar after item remove, the 1st line just removes item from registered but do not update headerPanel state
packages/devextreme/js/__internal/grids/grid_core/search/m_search.ts
Outdated
Show resolved
Hide resolved
| if (this._headerPanel && searchPanelOptions && searchPanelOptions.visible) { | ||
| return { | ||
| template: (data, index, container: dxElementWrapper | Element): void => { | ||
| if (this._headerPanel) { |
There was a problem hiding this comment.
This also seems redundant. If we’re not sure whether _headerPanel exists somewhere, we can use the optional chaining operator (?.) where needed.
There was a problem hiding this comment.
I prefer keep it here to ensure we append template to existing headerPanel (not before 1st render)
Also this way it is cleaner than multiple ? and skip-errors
packages/devextreme/js/__internal/grids/grid_core/search/m_search.ts
Outdated
Show resolved
Hide resolved
a437a97 to
731ff8c
Compare
|
|
||
| return items; | ||
| } | ||
| if (!this.headerPanel || !$element) { |
There was a problem hiding this comment.
kept check here for cleaner TS checks
No description provided.